package main

import (
	"fmt"

	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/tools/cache"
)

/*
*

# Indexer 示例

● type IndexFunc: 索引器函数，用来计算资源对象的索引值
● type Index：存储数据，类型是 map["namespace"]sets.pod
● type Indexers: 存储索引器，类型是 map["namespace"]MetaNamespaceIndexFunc
● type Indices：存储缓存器, 类型为 map["namespace"]map[namespace]sets.pod, 即 map["namespace"]Index
*/

func NamespaceIndexFunc(obj interface{}) (result []string, err error) {
	pod, ok := obj.(*v1.Pod)
	if !ok {
		return nil, fmt.Errorf("类型错误%v", err)
	}
	result = []string{pod.Namespace}

	return
}

func NodeNameIndexFunc(obj interface{}) (result []string, err error) {
	pod, ok := obj.(*v1.Pod)
	if !ok {
		return nil, fmt.Errorf("类型错误%v", err)
	}
	result = []string{pod.Spec.NodeName}

	return
}

func main() {
	// 实例一个indexer, 并建两个索引
	index := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{
		"namespace": NamespaceIndexFunc,
		"nodeName":  NodeNameIndexFunc,
	})

	// 模拟数据

	pod1 := &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "index-pod-1",
			Namespace: "default",
		},
		Spec: v1.PodSpec{
			NodeName: "node1",
		},
	}

	pod2 := &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "index-pod-2",
			Namespace: "default",
		},
		Spec: v1.PodSpec{
			NodeName: "node2",
		},
	}

	pod3 := &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "index-pod-3",
			Namespace: "kube-system",
		},
		Spec: v1.PodSpec{
			NodeName: "node3",
		},
	}

	// 加入indexer中
	_ = index.Add(pod1)
	_ = index.Add(pod2)
	_ = index.Add(pod3)

	// 查询
	pods, err := index.ByIndex("namespace", "default")
	if err != nil {
		panic(err)
	}
	for _, pod := range pods {
		fmt.Println(pod.(*v1.Pod).Name)
	}

	fmt.Println("-------------------------------------")

	// 查询
	pods2, err := index.ByIndex("nodeName", "node2")
	if err != nil {
		panic(err)
	}
	for _, pod := range pods2 {
		fmt.Println(pod.(*v1.Pod).Name)
	}

	/** 输出如下
	index-pod-1
	index-pod-2
	-------------------------------------
	index-pod-2
	*/

	/** indices.json

	{
		"namespace": {
			"default": ["index-pod-1", "index-pod-2"],
			"kube-system": ["index-pod-3"]
		},
		"nodeName": {
			"node2": ["index-pod-2", "index-pod-3"]
		}
	}
	*/
}
